package com.vip.zuul.controller;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.cloud.netflix.zuul.filters.Route;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute;
import org.springframework.cloud.netflix.zuul.web.ZuulController;
import org.springframework.cloud.netflix.zuul.web.ZuulHandlerMapping;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.baomidou.mybatisplus.plugins.Page;
import com.netflix.loadbalancer.DynamicServerListLoadBalancer;
import com.netflix.loadbalancer.IPing;
import com.netflix.loadbalancer.PingUrl;
import com.netflix.loadbalancer.Server;
import com.vip.zuul.common.web.BaseController;
import com.vip.zuul.common.web.ResponseVO;
import com.vip.zuul.configuration.VIPZuulRouteLocator;
import com.vip.zuul.service.IVipRouteService;
import com.vip.zuul.vo.RouteDTO;
import com.vip.zuul.vo.RouteReqVO;
import com.vip.zuul.vo.RouteResVO;

/**
 * Description : 
 * @Author Evan Liu
 * @Date 2018年11月13日
 */

@Controller
@RequestMapping("/admin/route")
public class ManageRoutesController extends BaseController{
	public final static Logger logger = LoggerFactory.getLogger(ManageRoutesController.class);

	@Autowired
	IVipRouteService routeService;
    @Autowired
    ZuulHandlerMapping zuulHandlerMapping;
    @Autowired
    private VIPZuulRouteLocator vipZuulRouteLocator;
    @Autowired
    private SpringClientFactory springClientFactory;
 
    @ResponseBody
    @GetMapping("/refresh")
    public ResponseVO refresh() {
    	routeService.refreshRoute();
        return getSuccess();
    }
    
    @ResponseBody
    @PostMapping("")
    public ResponseVO add(@RequestBody RouteReqVO reqVO) {
    	boolean result = false;
    	String id = reqVO.getZuulRoute().getId();
    	String path = reqVO.getZuulRoute().getPath();
    	String url= reqVO.getZuulRoute().getUrl();
    	String serviceId = reqVO.getZuulRoute().getServiceId();
    	Boolean retryable = reqVO.getZuulRoute().getRetryable();
    	
    	String prefix="/api/**";
    	Boolean stripPrefix = reqVO.getZuulRoute().isStripPrefix();
    	Set<String> ignoredHeaders = null;
    	
        //result = vipZuulRouteLocator.getRoutes().add(zuulRoute);
        RouteDTO dto = new RouteDTO();
        
        ZuulRoute zuulRoute = new ZuulRoute();
        zuulRoute.setId(id);
        zuulRoute.setPath(path);
        zuulRoute.setRetryable(retryable);
        zuulRoute.setServiceId(serviceId);
        zuulRoute.setStripPrefix(stripPrefix);
        zuulRoute.setUrl(url);
        dto.setZuulRoute(zuulRoute);
        
        dto.setBlackIP(reqVO.getBlockUrl());
        routeService.addRouteRules(dto);
        return getFromData(result);
    }
    
    @ResponseBody
    @DeleteMapping("/{id}")
    public ResponseVO del(@PathVariable String id) {
    	boolean result = routeService.removeRouteRules(id);;
        return getFromData(result);
    }
    
    @ResponseBody
    @GetMapping("")
    public ResponseVO search() {
        List<Route> result = vipZuulRouteLocator.getRoutes();
        List<RouteResVO> vipRules = new ArrayList<>();
        for (Route route : result) {
        	RouteResVO vip = new RouteResVO();
        	BeanUtils.copyProperties(route, vip);
        	String serviceId = vip.getZuulRoute().getId();
        	DynamicServerListLoadBalancer loadBalancer = (DynamicServerListLoadBalancer) springClientFactory.getLoadBalancer(serviceId);
        	if(loadBalancer!=null) {
        		String loadBalancerName = loadBalancer.getRule().getClass().getSimpleName();
        		IPing iping = loadBalancer.getPing();
        		String pingClass = iping.getClass().getSimpleName();
        		//NoOpPing;PingConstant;PingUrl;DummyPing
        		vip.setPingClassName(pingClass);
        		if(StringUtils.equals(pingClass, "PingUrl")) {
        			PingUrl urlPing = (PingUrl) iping;
        			vip.setPingUrl(urlPing.getPingAppendString());
        		}
        		vip.setBalancerName(loadBalancerName);
        		List<Server> oldServerList = loadBalancer.getServerListImpl().getUpdatedListOfServers();
        		String listServers = StringUtils.join(oldServerList, ",");
        		vip.setServers(listServers);
        	}
        	vipRules.add(vip);
		}
        
        Page page = new Page(1, result.size());
        page.setTotal(result.size());
        page.setRecords(vipRules);
        return getFromData(page);
    }
}


